from PIL import Image
import cv2
import numpy as np

def zoom_in(self, image, color):
    mask = np.linalg.norm(np.array(image) - color, axis=-1) < 20
    x, y, w, h = cv2.boundingRect(mask.astype(np.uint8))
    return (x, y, w + x, h + y)

if __name__ == "__main__":
    try:
        g_rate = 0.5
        img = Image.open("images/1.jpg")
        ALARM = 200, 42, 45
        BG = 76, 116, 139
        SELECTED = 37, 59, 151

        rect = zoom_in(img, BG)
        roi = img.crop(rect)
        mask = np.linalg.norm(np.array(roi) - ALARM, axis=-1) < 64
        node = cv2.morphologyEx(mask.astype(np.uint8), cv2.MORPH_OPEN, np.ones([2, 2]))
        line = mask ^ node
        node = cv2.morphologyEx(node, cv2.MORPH_DILATE, np.ones([7, 7]))
        boxes = cv2.connectedComponentsWithStats(node)[2][1:, :-1]
        boxes[:, 2:] += boxes[:, :2]
        selected = zoom_in(roi, SELECTED)
        _id = np.linalg.norm(boxes - selected, axis=-1).argmin()
        others = _id != np.arange(len(boxes))
        rank = []
        _b = boxes[_id]
        cx, cy = _b.reshape([2, 2]).mean(0)
        l, t, r, b = selected
        radius = int(max(r - l, b - t) / 2 ** g_rate)
        polar = cv2.linearPolar(mask.astype(np.uint8), (cx, cy), radius * 2, flags=cv2.WARP_FILL_OUTLIERS)
        integration = polar[:, polar.shape[1] // 5:].sum(1)
        conf = integration.max() / polar.shape[1]
        angle = integration.argmax() / polar.shape[0] * 2 * np.pi
        dx = np.cos(angle) * radius * 2
        dy = np.sin(angle) * radius * 2
        x, y = map(np.add, [cx, cy], [dx, dy])
        x, y = map(np.add, [x, y], rect[:2])
        cx, cy = map(np.add, [cx, cy], rect[:2])
        x, y, cx, cy = map(int, [x, y, cx, cy])
        if conf < 0.15:
            x, y = [None] * 2
        g_find_list = {'x': x, 'y': y, 'cx': cx, 'cy': cy}
        print(g_find_list)
    except:
        g_find_list = {'x': None, 'y': None, 'cx': None, 'cy': None}
        print(g_find_list)
